package controller.actions;

import model.controller.*;
import model.controller.UserController.AdministratorController;
import model.controller.UserController.BookmakerController;
import model.controller.UserController.ClientController;
import model.controller.UserController.UserController;
import model.user.Administrator;
import model.user.Bookmaker;
import model.user.Client;
import model.user.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegistrationAction implements Action {
    @Override
    public String perform(HttpServletRequest request, HttpServletResponse response) {
        String login = request.getParameter("login");
        String password = request.getParameter("password");
        String status = request.getParameter("status");

        if (dataNotMatches(request, login, password)) {
            return "/error.jsp";
        }

        HttpSession session = request.getSession(true);
        
        User user;
        UserController userController;

        if(status.equals("client")) {
            try {
                user = new Client(login,password);
                userController = new ClientController();
                addUser(login, session, user, userController);
                session.setAttribute("status","client");
                return "/client.jsp";
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (ControllerException e) {
                request.setAttribute("errorMessage", e.getMessage());
                return "/error.jsp";                
            }
        }
        
        if(status.equals("bookmaker")) {
            try {
                user = new Bookmaker(login,password);
                userController = new BookmakerController();
                addUser(login, session, user, userController);
                session.setAttribute("status","bookmaker");
                return "/bookmaker.jsp";
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (ControllerException e) {
                request.setAttribute("errorMessage", e.getMessage());
                return "/error.jsp";
            }
        }

        if(status.equals("administrator")) {
            try {
                user = new Administrator(login,password);
                userController = new AdministratorController();
                addUser(login, session, user, userController);
                session.setAttribute("status","administrator");
                return "/administrator.jsp";
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (ControllerException e) {
                request.setAttribute("errorMessage", e.getMessage());
                return "/error.jsp";
            }
        }

        return null;
    }

    private void addUser(String login, HttpSession session, User user, UserController userController) throws SQLException, ControllerException {
        userController.addUser(user);
        session.setAttribute("user",login);
        session.setAttribute("controller",userController);
    }

    private boolean dataNotMatches(HttpServletRequest request, String login, String password) {
        Pattern p = Pattern.compile("[a-zA-Z0-9]+");
        Matcher loginMatcher = p.matcher(login);
        Matcher passwordMatcher = p.matcher(password);

        if (!loginMatcher.matches() || !passwordMatcher.matches()) {
            request.setAttribute("errorMessage", "forbiden symbols in login/password ");
            return true;
        }
        return false;
    }
}
